﻿using CY_MVC.HttpHandlers;
using Fasterflect;
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Web;

namespace CY_MVC.Core
{
    internal static class ControllerContext
    {
        internal static IDictionary<string, Type> Controllers = new Dictionary<string, Type>();
        private static readonly Type ResourceControllerType = typeof(ResourceController);


        internal static void Init()
        {
            var AssemblyController = Assembly.Load(StaticConfig.ControllerName);
            if (AssemblyController == null)
            {
                throw new Exception("网站Bin目录下不存在" + StaticConfig.ControllerName + "项目引用文件");
            }
            Controllers = new Dictionary<string, Type>();
            foreach (var item in AssemblyController.TypesImplementing<BaseController>())
            {
                Controllers.Add(item.FullName.Replace(StaticConfig.ControllerName + ".", string.Empty).ToLowerInvariant(), item);
            }
        }

        internal static BaseController GetController(string p_ControllerName)
        {
            if (Controllers.ContainsKey(p_ControllerName))
            {
                return (BaseController)Activator.CreateInstance(Controllers[p_ControllerName]);
            }
            return null;
        }


        private static ResourceController GetResourceController()
        {
            return (ResourceController)Activator.CreateInstance(ResourceControllerType);
        }

        private const string Iiem_ControllerName = "_ControllerName_";
        private const string Iiem_RequestUrl = "_RequestUrl_";

        internal static void SetController(object p_Sender, EventArgs p_E)
        {
            var Context = ((HttpApplication)p_Sender).Context;
            var ControllerName = WebUrl.ControllerName(Context);
            if (Controllers.ContainsKey(ControllerName))
            {
                Context.Items[Iiem_RequestUrl] = Context.Request.Url.AbsolutePath;
                Context.Items[Iiem_ControllerName] = ControllerName;
                Context.RewritePath("~"+StaticConfig.MVCHandler);
            }
        }

        internal static void RunController(object p_Sender, EventArgs p_E)
        {
            var Context = ((HttpApplication)p_Sender).Context;
            var CYMVC_AbsolutePath = Context.Request.ApplicationPath == "/" ? StaticConfig.MVCHandler : Context.Request.ApplicationPath + StaticConfig.MVCHandler;
            if (!string.Equals(Context.Request.Url.AbsolutePath, CYMVC_AbsolutePath, StringComparison.OrdinalIgnoreCase)) return;
            if (Context.Items.Contains(Iiem_RequestUrl) && Context.Items.Contains(Iiem_ControllerName))
            {
                Context.RewritePath(Context.Items[Iiem_RequestUrl].ToString());
                Context.RemapHandler(GetController(Context.Items[Iiem_ControllerName].ToString()));
                Context.Items.Remove(Iiem_RequestUrl);
                Context.Items.Remove(Iiem_ControllerName);
            }
            else if (!string.IsNullOrEmpty(Context.Request.QueryString["csskey"]) |
                     !string.IsNullOrEmpty(Context.Request.QueryString["jskey"]))
            {
                Context.RemapHandler(GetResourceController());
            }
        }
    }
}
